import gradio as gr
import os
import base64
from openai import OpenAI

# 获取根路径
root_path = os.environ.get("ROOT_PATH", "")


# 初始化营养分析助手
class NutritionAnalyzer:
    def __init__(self, api_key: str, model: str = "ernie-4.5-turbo-vl"):
        self.api_key = api_key
        self.model = model
        self.base_url = "https://aistudio.baidu.com/llm/lmapi/v3"
        self.client = OpenAI(
            api_key=self.api_key,
            base_url=self.base_url,
            timeout=60.0
        )

    def encode_image(self, image_path: str) -> str:
        """将图片编码为base64"""
        with open(image_path, "rb") as image_file:
            return base64.b64encode(image_file.read()).decode("utf-8")

    def analyze_food_image(self, image_path: str) -> dict:
        """分析食物图片并提取营养信息"""
        if image_path is None:
            return {"error": "请上传食物图片！"}

        try:
            # 将图片转换为base64
            base64_image = self.encode_image(image_path)

            prompt = """请仔细分析这张图片中的内容，严格按照以下要求处理：

如果图片中包含食物：
1. 识别图片中的所有食物名称
2. 估算每种食物的重量（克）
3. 估算每种食物的营养成分：
   - 碳水化合物（克）
   - 脂肪（克）
   - 蛋白质（克）
   - 热量（千卡）

请以清晰易读的Markdown表格形式返回结果，表格必须包含以下列：
| 食物名称 | 重量(g) | 碳水(g) | 脂肪(g) | 蛋白质(g) | 热量(kcal) |

在列出所有食物后，请添加一行总计，格式如下：
| **总计** | [总重量] | [总碳水] | [总脂肪] | [总蛋白质] | [总热量] |

然后，请根据中国居民膳食指南，对这顿食物的营养构成进行评分（满分100分），并给出合理的改进建议。

评分标准参考：

总热量是否适中（一餐建议热量：600-800千卡）

三大营养素供能比：碳水化合物50-65%，脂肪20-30%，蛋白质10-15%

食物多样性（种类是否丰富）

如果图片中没有任何食物，请直接回答："这张图片中没有检测到食物。"

请确保回答简洁明了，重点突出营养信息表格。"""

            # 调用API
            completion = self.client.chat.completions.create(
                model=self.model,
                messages=[
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "text",
                                "text": prompt
                            },
                            {
                                "type": "image_url",
                                "image_url": {
                                    "url": f"data:image/jpeg;base64,{base64_image}",
                                    "detail": "high"
                                }
                            }
                        ]
                    }
                ],
                temperature=0.3,
                stream=False
            )

            result = completion.choices[0].message.content
            return {"success": True, "analysis": result}

        except Exception as e:
            return {"error": f"分析失败：{str(e)}"}

    def generate_diet_plan(self, age_range, habit, region):
        """生成个性化食谱"""
        try:
            region_info = f"用户来自{region}地区，" if region else "通用地区"

            prompt = f"""作为一名专业营养师，请为{age_range}年龄段、{habit}目标的人群设计一份健康的一日三餐食谱。

{region_info}请充分考虑当地饮食习惯、特色食材和饮食文化。

请按照以下格式提供详细的食谱：

### 用户信息
- **年龄段**: {age_range}
- **健康目标**: {habit}
- **地域特点**: {region_info}

### 🌅 早餐
- **主食**: [具体食物及分量，考虑地域特色]
- **蛋白质**: [具体食物及分量] 
- **蔬果**: [具体食物及分量]
- **饮品**: [具体食物及分量]
- **估算热量**: [数值]千卡
- **地域特色**: [结合地区特点说明]

### 🏙️ 午餐
- **主食**: [具体食物及分量，考虑地域特色]
- **蛋白质**: [具体食物及分量]
- **蔬菜**: [具体食物及分量]
- **其他**: [具体食物及分量]
- **估算热量**: [数值]千卡
- **地域特色**: [结合地区特点说明]

### 🌃 晚餐
- **主食**: [具体食物及分量，考虑地域特色]
- **蛋白质**: [具体食物及分量]
- **蔬菜**: [具体食物及分量]
- **其他**: [具体食物及分量]
- **估算热量**: [数值]千卡
- **地域特色**: [结合地区特点说明]

### 📊 全日营养总览
| 营养素 | 含量 |
|--------|------|
| 总热量 | [数值]千卡 |
| 碳水化合物 | [数值]克 |
| 蛋白质 | [数值]克 |
| 脂肪 | [数值]克 |

### 💡 营养师建议
[根据用户年龄、目标和地域特点提供针对性的营养建议，特别考虑{region if region else "通用"}地区的饮食文化]

请确保食谱符合{age_range}年龄段的营养需求，适合{habit}目标，并充分考虑{region if region else "通用"}地区的饮食习惯和特色食材。"""

            # 调用API
            completion = self.client.chat.completions.create(
                model=self.model,
                messages=[
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "text",
                                "text": prompt
                            }
                        ]
                    }
                ],
                temperature=0.7,
                stream=False
            )

            result = completion.choices[0].message.content
            return {"success": True, "diet_plan": result}

        except Exception as e:
            return {"error": f"生成食谱失败：{str(e)}"}


# 初始化分析器
nutrition_analyzer = NutritionAnalyzer(
    api_key="8f6070c62cfbf3388cd93436705bb28716164503"
)


def analyze_food_nutrition(image):
    """Gradio接口函数：分析食物营养"""
    if image is None:
        return "## 📊 食物营养分析结果\n\n请上传包含食物的图片！"

    result = nutrition_analyzer.analyze_food_image(image)

    if "error" in result:
        return f"## ❌ 错误\n\n{result['error']}"
    elif "success" in result and result["success"]:
        analysis_text = result["analysis"]

        # 检查是否包含"没有食物"的提示
        if "没有检测到食物" in analysis_text or "没有任何食物" in analysis_text:
            return f"## 🍽️ 分析结果\n\n{analysis_text}"
        else:
            # 返回格式化的分析结果
            return f"## 📊 食物营养分析结果\n\n{analysis_text}"
    else:
        return "## ⚠️ 提示\n\n分析完成，但未能获取到有效结果。"


def chat_food_question(question):
    """食物营养问答"""
    if not question.strip():
        return "## 💡 营养专家解答\n\n请输入您的营养相关问题！"

    try:
        client = OpenAI(
            api_key="8f6070c62cfbf3388cd93436705bb28716164503",
            base_url="https://aistudio.baidu.com/llm/lmapi/v3",
        )

        completion = client.chat.completions.create(
            model="ernie-4.5-turbo-vl",
            messages=[
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "text",
                            "text": f"你是一位营养专家，请专业解答以下营养相关问题：\n\n问题：{question}\n\n请提供科学、准确的营养建议，如果涉及具体数据请清晰标明。"
                        }
                    ]
                }
            ],
            stream=False,
        )

        result = completion.choices[0].message.content
        return f"## 💡 营养专家解答\n\n{result}"

    except Exception as e:
        return f"## ❌ 错误\n\n对话失败：{str(e)}"


def generate_healthy_diet(age_range, habit, region):
    """生成健康食谱"""
    if not age_range or not habit:
        return "## 🍽️ 个性化健康食谱\n\n请选择年龄段和健康目标！"

    result = nutrition_analyzer.generate_diet_plan(age_range, habit, region)

    if "error" in result:
        return f"## ❌ 错误\n\n{result['error']}"
    elif "success" in result and result["success"]:
        diet_plan = result["diet_plan"]
        return f"## 🍽️ 个性化健康食谱\n\n{diet_plan}"
    else:
        return "## ⚠️ 提示\n\n食谱生成完成，但未能获取到有效结果。"


def create_nutrition_interface():
    """创建营养分析界面"""
    with gr.Blocks(title="🍎 智能食物营养分析助手", theme=gr.themes.Soft()) as demo:
        gr.Markdown("# 🍎 智能食物营养分析助手")
        gr.Markdown("基于文心一言4.5多模态能力的智能营养分析助手")

        with gr.Tabs():
            with gr.TabItem("📷 图片营养分析"):
                with gr.Row():
                    with gr.Column():
                        gr.Markdown("### 上传食物图片")
                        image_input = gr.Image(
                            type="filepath",
                            label="上传食物图片",
                            sources=["upload", "webcam", "clipboard"]
                        )
                        analyze_btn = gr.Button(
                            "🔍 分析营养成分",
                            variant="primary",
                            scale=1
                        )

                        gr.Markdown("""
                        **使用说明：**
                        - 上传清晰的包含食物的图片
                        - 支持常见食物、餐盘、包装食品等
                        - 系统会自动识别食物并分析营养成分
                        """)

                    with gr.Column():
                        gr.Markdown("### 分析结果")
                        analysis_output = gr.Markdown(
                            label="营养分析",
                            value="## 📊 食物营养分析结果\n\n请上传图片并点击分析按钮查看结果"
                        )

                analyze_btn.click(
                    fn=analyze_food_nutrition,
                    inputs=image_input,
                    outputs=analysis_output
                )

            with gr.TabItem("💬 营养问答"):
                with gr.Row():
                    with gr.Column():
                        gr.Markdown("### 营养问题咨询")
                        text_input = gr.Textbox(
                            label="输入您的问题",
                            placeholder="例如：苹果的营养价值有哪些？如何控制体重期间的饮食搭配？",
                            lines=4
                        )
                        chat_btn = gr.Button(
                            "🤖 咨询专家",
                            variant="primary",
                            scale=1
                        )

                    with gr.Column():
                        gr.Markdown("### 专家回答")
                        chat_output = gr.Markdown(
                            label="专家解答",
                            value="## 💡 营养专家解答\n\n请输入问题并点击咨询按钮"
                        )

                chat_btn.click(
                    fn=chat_food_question,
                    inputs=text_input,
                    outputs=chat_output
                )

            with gr.TabItem("🍽️ 智能食谱生成"):
                with gr.Row():
                    with gr.Column():
                        gr.Markdown("### 个人信息设置")

                        age_range = gr.Dropdown(
                            choices=[
                                "儿童(8-12岁)",
                                "青少年(13-17岁)",
                                "青年(18-35岁)",
                                "中年(36-59岁)",
                                "老年(60-80岁)"
                            ],
                            label="年龄段",
                            value="青年(18-35岁)"
                        )

                        habit = gr.Dropdown(
                            choices=[
                                "均衡饮食",
                                "减脂瘦身",
                                "增肌增重",
                                "控制体重",
                                "增强免疫力",
                                "改善消化",
                                "低糖饮食",
                                "高蛋白饮食"
                            ],
                            label="健康目标",
                            value="均衡饮食"
                        )

                        gr.Markdown("### 地区选择")
                        region = gr.Dropdown(
                            choices=[
                                "华北地区（北京、天津、河北、山西、内蒙古）",
                                "东北地区（辽宁、吉林、黑龙江）",
                                "华东地区（上海、江苏、浙江、安徽、福建、江西、山东）",
                                "华中地区（河南、湖北、湖南）",
                                "华南地区（广东、广西、海南）",
                                "西南地区（重庆、四川、贵州、云南、西藏）",
                                "西北地区（陕西、甘肃、青海、宁夏、新疆）",
                                "港澳台地区"
                            ],
                            label="选择您所在的地区",
                            value="华东地区（上海、江苏、浙江、安徽、福建、江西、山东）",
                            allow_custom_value=True
                        )

                        gr.Markdown("""
                        **地区说明：**
                        - 选择您所在的地区，系统会根据当地饮食习惯生成更合适的食谱
                        - 如果您有特定偏好，也可以手动输入其他地区
                        """)

                        generate_btn = gr.Button(
                            "🍳 生成健康食谱",
                            variant="primary",
                            scale=1
                        )

                    with gr.Column():
                        gr.Markdown("### 个性化健康食谱")
                        diet_output = gr.Markdown(
                            label="食谱结果",
                            value="## 🍽️ 个性化健康食谱\n\n请设置个人信息并点击生成按钮"
                        )

                # 生成食谱按钮点击事件
                generate_btn.click(
                    fn=generate_healthy_diet,
                    inputs=[age_range, habit, region],
                    outputs=diet_output
                )

            with gr.TabItem("📚 使用指南"):
                gr.Markdown("""
                ## 使用指南

                ### 📷 图片营养分析
                1. 点击"上传食物图片"或使用摄像头拍摄
                2. 选择包含食物的清晰图片
                3. 点击"分析营养成分"按钮
                4. 查看详细的营养分析报告

                ### 💬 营养问答
                1. 在输入框中描述您的营养相关问题
                2. 点击"咨询专家"按钮
                3. 获取专业的营养建议和解答

                ### 🍽️ 智能食谱生成
                1. 选择您的年龄段和健康目标
                2. 选择您所在的地区（系统会根据地区饮食习惯调整食谱）
                3. 点击"生成健康食谱"按钮
                4. 获取个性化的三餐食谱和营养建议

                ### 🎯 支持的功能
                - 食物识别与营养成分分析
                - 热量估算
                - 营养均衡建议
                - 饮食搭配指导
                - 个性化食谱生成（结合年龄、目标和地区饮食文化）

                ### ⚠️ 注意事项
                - 分析结果为估算值，仅供参考
                - 实际营养值可能因烹饪方式等因素变化
                - 如有特殊健康需求，请咨询专业营养师
                """)

        gr.Markdown("""
        ---
        <div align="center">

        **让营养分析更智能，让健康管理更简单！** 🥗

        *基于文心一言4.5多模态技术*

        </div>
        """)

    return demo


# 创建并启动应用
if __name__ == "__main__":
    print("🚀 启动智能食物营养分析助手...")
    print("📱 访问地址: http://localhost:7860")
    print("-" * 50)

    demo = create_nutrition_interface()

    try:
        demo.launch(
            server_name="0.0.0.0",
            server_port=7860,
            root_path=root_path,
            share=True,
            inbrowser=False
        )
    except Exception as e:
        print(f"启动失败: {e}")
        import traceback

        traceback.print_exc()